from rest_framework import serializers
from .models import *
from rest_framework_jwt.settings import api_settings
from django.contrib.auth import authenticate
from rest_framework.exceptions import APIException
from django.conf import settings
import os

jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER


class UserLoginSerializer(serializers.ModelSerializer):
    username = serializers.CharField()

    class Meta:
        model = Userinfo
        fields = ['username', 'password']

    def _obtain_user(self, attrs):
        username = attrs.get('username')
        password = attrs.get('password')
        user = authenticate(username=username, password=password)
        if user:
            return user
        else:
            raise APIException('账号尚未激活,或用户名密码错误')

    def _obtain_token(self, user):
        try:
            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)
            return token
        except Exception as e:
            raise APIException(str(e))

    def validate(self, attrs):
        user = self._obtain_user(attrs)
        token = self._obtain_token(user)
        request = self.context.get('request')
        self.context['user_id'] = user.id
        self.context['username'] = user.username
        self.context['token'] = token
        self.context['icon'] = f"http://{request.META.get('HTTP_HOST')}{settings.MEDIA_URL}{str(user.icon)}"
        self.context['role'] = user.role
        return attrs


class StudentClassSerializer(serializers.ModelSerializer):
    class Meta:
        model = StudentClass
        fields = ['id', 'name', 'count', 'time']
        extra_kwargs = {
            'id': {'read_only': True},
            'time': {'read_only': True},
            'count': {'read_only': True},
        }


class StudentRegisterSerializer(serializers.ModelSerializer):
    confirm_password = serializers.CharField()

    class Meta:
        model = Userinfo
        fields = ['username', 'password', 'student_class', 'confirm_password']

    def validate(self, attrs):
        confirm_password = attrs.pop('confirm_password')
        if confirm_password != attrs.get('password'):
            raise APIException('两次密码不一致,请确认无误后提交注册')
        attrs['is_active'] = 0
        Userinfo.objects.create_user(**attrs)
        return attrs


class StudentListSerializer(serializers.ModelSerializer):
    class Meta:
        model = Userinfo
        fields = ['id', 'username', 'mobile', 'is_active', 'class_name', 'paper_count', 'email', 'join_time',
                  'student_class']
        extra_kwargs = {
            'id': {'read_only': True},
            'class_name': {'read_only': True},
            'paper_count': {'read_only': True},
            'date_joined': {'read_only': True},
            'student_class': {'read_only': True},
        }


class EditStudentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Userinfo
        fields = ['id', 'username', 'mobile', 'email', 'student_class']
        extra_kwargs = {
            'username': {'read_only': True},
            'id': {'read_only': True},
        }

    def validate(self, attrs):
        student_id = self.context.get('user_id')
        username = self.context.get('username')
        attrs['username'] = username
        Userinfo.objects.filter(pk=student_id).update(**attrs)
        return attrs


class EditUserinfoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Userinfo
        fields = ['id', 'username', 'mobile', 'email', 'student_class', 'icon', 'role_name', 'icon_url']
        extra_kwargs = {
            'id': {'read_only': True},
            'icon': {'read_only': True},
            'role_name': {'read_only': True},
            'icon_url': {'read_only': True},
            'username': {'read_only': True},
            'email': {'read_only': True},
            'student_class': {'read_only': True},
        }

    def validate(self, attrs):
        viewer = self.context.get('viewer')
        if viewer.action == 'update_userinfo':
            self._update_userinfo(attrs)
        return attrs

    def _update_userinfo(self, attrs):
        context = self.context
        user_id = context.pop('user_id')
        context.pop('viewer')
        context['mobile'] = attrs.get('mobile')
        icon = context.pop('icon')
        Userinfo.objects.filter(pk=user_id).update(**context)
        if not isinstance(icon, str):
            user = Userinfo.objects.filter(pk=user_id).first()
            user.icon = icon
            user.save()
        return
